package com.fencing_squad.homo.util;

import com.fencing_squad.homo.util.function.FunctionVoid;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.animation.timelinecurves.CubicBezierCurve;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.multimodalinput.event.TouchEvent;

public class AnimationConfig {
    public final static CubicBezierCurve CURVE_1 = new CubicBezierCurve((float)0.43, (float)0.11, (float)0.37, (float)0.99);
    public final static CubicBezierCurve CURVE_2 = new CubicBezierCurve((float)0, (float)0.38, (float)0.52, (float)1.42);
    public final static CubicBezierCurve CURVE_3 = new CubicBezierCurve((float)0.02, (float)0.52, (float)0.47, (float)0.99);
    public final static int THEME_COLOR = 0xa98bdb;
    public final static int THEME_COLOR_DARK = 0x997bcb;

    public static AnimatorProperty getWelcomeAnim(Component component) {
        AnimatorProperty property = component.createAnimatorProperty();
        property.alpha(0).setDelay(3000).setDuration(500).setCurve(AnimationConfig.CURVE_1);
        return property;
    }

    public static AnimatorProperty getDialogShowAnim(Component component) {
        AnimatorProperty property = component.createAnimatorProperty();
        property.alphaFrom(0).alpha(1).scaleXFrom((float)0.5).scaleX(1).scaleYFrom((float)0.5).scaleY(1).setDuration(300).setCurve(AnimationConfig.CURVE_2);
        return property;
    }

    public static AnimatorValue getOfferInputShowAnim(Component component) {
        int top = component.getTop();
        AnimatorValue animatorValue = new AnimatorValue();
        animatorValue.setCurve(CURVE_3);
        animatorValue.setDuration(300);
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                component.setTop((int) (- value *  (top - 490) ) + top);
            }
        });
        return animatorValue;
    }

    public static AnimatorValue getCardAnim(Component component, int fromX, int fromY, int toX, int toY) {
        AnimatorValue animatorValue = new AnimatorValue();
        animatorValue.setCurve(CURVE_3);
        animatorValue.setDuration(300);
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                component.setLeft((int) (value * (toX - fromX)) + fromX);
                component.setTop((int) (value * (toY - fromY)) + fromY);
            }
        });
        return animatorValue;
    }

    public static AnimatorValue getOfferInputHideAnim(Component component) {
        int top = component.getTop();
        AnimatorValue animatorValue = new AnimatorValue();
        animatorValue.setCurve(CURVE_3);
        animatorValue.setDuration(300);
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                component.setTop((int) ( value *  (1920 - top) ) + top);
            }
        });
        return animatorValue;
    }

    public static AnimatorValue getOfferInfoShowAnim(Component component) {
        int top = component.getTop();
        AnimatorValue animatorValue = new AnimatorValue();
        animatorValue.setCurve(CURVE_3);
        animatorValue.setDuration(300);
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                component.setTop((int) ( value *  (570 - top) ) + top);
            }
        });
        return animatorValue;
    }

    public static AnimatorValue getOfferInfoHideAnim(Component component) {
        int top = component.getTop();
        AnimatorValue animatorValue = new AnimatorValue();
        animatorValue.setCurve(CURVE_3);
        animatorValue.setDuration(300);
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                component.setTop((int) ( value *  (1860 - top) ) + top);
            }
        });
        return animatorValue;
    }

    public static void setInitAnimation(Component component, AnimatorProperty startAnimation, AnimatorProperty stopAnimation) {
        // 设置开始和结束动画
        component.setBindStateChangedListener(new Component.BindStateChangedListener() {
            @Override
            public void onComponentBoundToWindow(Component component) {
                if(startAnimation != null) {
                    startAnimation.start();
                }
            }
            @Override
            public void onComponentUnboundFromWindow(Component component) {
                if(stopAnimation != null) {
                    stopAnimation.start();
                }
            }
        });
    }

    public static void setAnimationListener(AnimatorGroup group, FunctionVoid end, FunctionVoid start) {
        // 设置动画事件监听(可以传入函数指针)
        group.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
                if (start != null) {
                    start.func();
                }
            }

            @Override
            public void onEnd(Animator animator) {
                if (end != null) {
                    end.func();
                }
            }

            @Override
            public void onStop(Animator animator) {}

            @Override
            public void onCancel(Animator animator) {}

            @Override
            public void onPause(Animator animator) {}

            @Override
            public void onResume(Animator animator) {}
        });
    }

    public static void setClickAnimation(Component component, Context context, int touchId, int leaveId) {
        ShapeElement elementTouch = new ShapeElement(context, touchId);
        ShapeElement elementLeave = new ShapeElement(context, leaveId);

        component.setTouchEventListener((comp, touchEvent) -> {
            if(touchEvent.getAction() == TouchEvent.PRIMARY_POINT_DOWN && comp.isClickable()) {
                comp.setBackground(elementTouch);
            }
            else if (touchEvent.getAction() == TouchEvent.PRIMARY_POINT_UP && comp.isClickable()) {
                comp.setBackground(elementLeave);
            }
            return true;
        });
    }

    public static void setClickAnimation(Text text, int touchValue, int leaveValue) {
        Color touchColor = new Color(touchValue - 0xffffff -1);
        Color leaveColor = new Color(leaveValue - 0xffffff -1);

        text.setTouchEventListener((comp, touchEvent) -> {
            if(touchEvent.getAction() == TouchEvent.PRIMARY_POINT_DOWN && comp.isClickable()) {
                ((Text)comp).setTextColor(touchColor);
            }
            else if (touchEvent.getAction() == TouchEvent.PRIMARY_POINT_UP && comp.isClickable()) {
                ((Text)comp).setTextColor(leaveColor);
            }
            return true;
        });
    }

    public static void setBackground(Component component, Context context, int resId) {
        ShapeElement element = new ShapeElement(context, resId);
        component.setBackground(element);
    }
}
